﻿using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using Common.Logging;
using Newtonsoft.Json;
using User.Api.Helpers;

namespace User.Api.Pipeline.ActionFilters
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class UserIdRequiredAttribute : AuthorizationFilterAttribute
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof(UserIdRequiredAttribute));

        public override void OnAuthorization(HttpActionContext actionContext)
        {
            if (actionContext == null)
                throw new ArgumentNullException(nameof(actionContext));

            var canSkip = SkipAuthorization(actionContext);

            var userInfo = GetUserId(actionContext.Request);

            // 调式用
            var querystrings = actionContext.Request.RequestUri.ParseQueryString();
            if (querystrings.AllKeys.Contains("openid"))
            {
                var openid = querystrings["openid"];

                if (openid == "oRE9huDfWvbwDeQ2ftcyhJtsb6iM")
                {
                    AzUser.SetInApi(actionContext.Request, 2, "oRE9huDfWvbwDeQ2ftcyhJtsb6iM");

                    return;
                }
                //AzUser.SetInApi(actionContext.Request, 2, openid);

                //return;
            }

            if (userInfo != null)
            {
                AzUser.SetInApi(actionContext.Request, userInfo.Item1, userInfo.Item2);
            }

            if (userInfo == null && !canSkip)
                HandleUnauthorizedRequest(actionContext);
        }

        private bool SkipAuthorization(HttpActionContext actionContext)
        {
            return actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any<AllowAnonymousAttribute>() ||
                actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any<AllowAnonymousAttribute>();
        }

        private void HandleUnauthorizedRequest(HttpActionContext actionContext)
        {
            actionContext.Response = actionContext.ControllerContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
        }

        private Tuple<long, string> GetUserId(HttpRequestMessage request)
        {
            try
            {
                CookieHeaderValue cookie = request.Headers.GetCookies("AzuCookie").FirstOrDefault();

                if (cookie != null)
                {
                    //此处系统会自动UrlDecode
                    var token = cookie["AzuCookie"].Value;
                    // token = token.UrlEncode();
                    var userId = 0L;
                    var openId = "";

                    var isVerified = LocalUserTokenHelper.VerifyLocalToken(token, out userId, out openId);

                    if (isVerified)
                    {
                        return new Tuple<long, string>(userId, openId);
                    }
                    else
                    {
                        return null;
                    }
                }
                return null;
            }
            catch (Exception ex)
            {
                Logger.Error(JsonConvert.SerializeObject(ex));
                return null;
            }
        }
    }
}